package bean;

import java.io.IOException;
import java.io.Serializable;
import java.security.Principal;
import java.util.Iterator;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import dao.DoctorDAO;
import dao.JPA;
import dao.UserDAO;
import entity.User;

@ManagedBean
@ViewScoped
public class LoginBean implements Serializable {
	
	@Inject
	private LocaleBean localeBean;
	@Inject
	private ActiveSessionsStoreBean usersBean;	
	@Inject @JPA
	private UserDAO userDAO;
	@Inject @JPA
	private DoctorDAO doctorDAO;	
	private User user = new User();
	private String targetURI;

	public LoginBean() {	
		setTargetURI();	
	}

	public String login() {				
		FacesContext context = FacesContext.getCurrentInstance();
		if(userDAO.selectUserByName(user.getName()) != null) {
			if(userDAO.selectRolesCountByUserName(user.getName()) == 0) {
				String excString = localeBean.getBundle().getString("you.are.banned");
				context.addMessage("loginForm:loginError", new FacesMessage(FacesMessage.SEVERITY_ERROR, excString, excString));
				return null;
			}			
		}		
		HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();		
		try {
			Principal userPrincipal = request.getUserPrincipal();			
			if (userPrincipal != null) {
				request.logout();
			}
			request.login(user.getName(), user.getPass());
			HttpSession session = request.getSession(false);	
			session.setAttribute("userName", user.getName()); // To be able to find session by user name
			usersBean.addSession(session);
			user = userDAO.selectUserByName(user.getName());
			if (request.isUserInRole("Doctor") && doctorDAO.selectDoctorByUserId(user.getId()) == null)
				return "doctor_register";
			if (targetURI != null) {
				FacesContext.getCurrentInstance().getExternalContext().redirect(targetURI);
			} else {
				return "back"; // This by default leads to main menu
			}
		} catch (ServletException e) {
			e.printStackTrace(); 			
			String excString = localeBean.getBundle().getString("invalid.login.or.pass");
			context.addMessage("loginForm:loginError", new FacesMessage(FacesMessage.SEVERITY_ERROR, excString, excString));
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return null;
	}

	public String logout() {
		FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
		return "login";
	}

	private void setTargetURI() {		
		targetURI = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
		if (targetURI != null) {			
			Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();			
			if (paramMap.size() > 0) {
				Iterator<String> it = paramMap.keySet().iterator();
				String key = it.next();
				String value = paramMap.get(key);
				targetURI += "?" + key + "=" + value;
				while (it.hasNext()) {
					key = it.next();
					value = paramMap.get(key);
					targetURI += "&" + key + "=" + value;
				}
			}
		}
	}
	
	public User getUser() {
		return user;
	}

}